package org.shalma.internal.client;

import org.shalma.client.Callback;
import org.shalma.client.Persistence;
import org.shalma.client.security.Security;
import org.shalma.client.view.View;
import org.shalma.internal.client.view.EntityView;
import org.shalma.model.Person;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.Widget;

public class Shell extends Composite implements ValueChangeHandler<String> {

	public static final String ME_TOKEN = "me";
	public static final String LOGIN_TOKEN = "!login";
	public static final String SEARCH_TOKEN = "!";

	interface Binder extends UiBinder<Widget, Shell> {
	}

	private static Binder binder = GWT.create(Binder.class);

	@UiField
	HorizontalPanel linksPanel;

	@UiField
	DeckPanel viewer;

	@UiField
	public Style style;

	private EntityView entityView;
	private SearchView searchView;
	private LoginView loginView;
	private Image imageLoading;

	public Shell() {

		Window.enableScrolling(false);
		Window.setMargin("0px");

		initWidget(binder.createAndBindUi(this));

		links();

		History.addValueChangeHandler(this);
		String token = History.getToken();
		if ("".equals(token))
			History.newItem(SEARCH_TOKEN);
		else
			History.fireCurrentHistoryState();
	}

	@Override
	public void onValueChange(ValueChangeEvent<String> event) {

		String token = event.getValue();

		View view;

		if (token.equals(LOGIN_TOKEN)) {

			if (loginView == null) {
				loginView = new LoginView();
				viewer.add(loginView);
				loginView.index = viewer.getWidgetCount() - 1;
			}

			view = loginView;

		} else if (token.startsWith(SEARCH_TOKEN)) {

			if (searchView == null) {
				searchView = new SearchView();
				viewer.add(searchView);
				searchView.index = viewer.getWidgetCount() - 1;
			}

			view = searchView;

		} else {

			if (entityView == null) {

				entityView = new EntityView();
				viewer.add(entityView);
				entityView.index = viewer.getWidgetCount() - 1;
			}

			entityView.update(token);
			view = entityView;
		}

		viewer.showWidget(view.index);
		view.onShow();
	}

	void links() {

		ShellIcons icons = ShellIcons.instance;

		addLink(SEARCH_TOKEN, icons.search(), "Search");

		imageLoading = new Image(icons.loading());
		linksPanel.add(imageLoading);

		Security.instance.getUser(new Callback<Person>() {
			@Override
			public void onSuccess(Person me) {
				links_async(me);
			}
		});

	}

	void links_async(Person me) {

		linksPanel.remove(imageLoading);

		ShellIcons icons = ShellIcons.instance;

		if (me != null) {

			addLink(ME_TOKEN, icons.user(), "Me");

			PushButton logout = new PushButton(new Image(icons.logout()));
			logout.setTitle("Logout");
			logout.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					Window.Location.replace(createLogoutURL());
				}
			});
			linksPanel.add(logout);

		} else {
			addLink(LOGIN_TOKEN, icons.login(), "Login");
		}

	}

	void addLink(final String token, ImageResource image, String name) {

		PushButton button = new PushButton(new Image(image));
		button.setTitle(name);
		button.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				History.newItem(token);
			}
		});
		// imageLink.addStyleName(style.link());
		linksPanel.add(button);
	}

	String createLogoutURL() {

		String href;

		if (GWT.isProdMode()) {
			href = GWT.getHostPageBaseURL();
			href += "_ah/openid_logout?continue=";
			href += Document.get().getURL();
		} else {
			href = "/_ah/logout?continue=/?gwt.codesvr=127.0.0.1:9997#";
			href += History.getToken();
		}

		return href;
	}

	interface Style extends CssResource {

		String link();
	}
}
